package cn.mw.cmdb.service.impl;

import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.enums.MonitorModeType;
import cn.mw.cmdb.param.ComponentLayoutInfoExcelExportParam;
import cn.mw.cmdb.param.SpecificationSearchParam;
import cn.mw.cmdb.param.TemplateExcelImportParam;
import cn.mw.cmdb.param.VendorSearchParam;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.util.ExcelUtils;
import cn.mw.components.mongodb.entity.SearchParam;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.google.common.base.Strings;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.mw.cmdb.util.ValConvertUtil.strValueConvert;

@Slf4j
public class ComponentLayoutExcelImportListener extends AnalysisEventListener<ComponentLayoutInfoExcelExportParam> {

    private final HttpServletResponse response;

    private CmdbServiceManage cmdbServiceManage;

    /**
     * 文件名称
     */
    private String fileName;

    /**
     * 操作人员名称
     */
    private String operatorName;

    /**
     * 每隔100条存储数据库，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 100;

    /**
     * 解析成功的数据
     */
    List<ComponentLayoutInfoExcelExportParam> list = new ArrayList<>();

    /**
     * 解析失败的数据
     */

    public ComponentLayoutExcelImportListener(HttpServletResponse response, String fileName, String operatorName, CmdbServiceManage cmdbServiceManage) {
        this.response = response;
        this.fileName = fileName;
        this.operatorName = operatorName;
        this.cmdbServiceManage = cmdbServiceManage;
    }

    /**
     * When analysis one row trigger invoke function.
     *
     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @SneakyThrows
    @Override
    public void invoke(ComponentLayoutInfoExcelExportParam data, AnalysisContext context) {
        list.add(data);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }

    /**
     * if have something to do after all analysis
     *
     * @param context
     */
    @SneakyThrows
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        if (list.size() > 0) {
            saveData();
            log.info("所有数据解析完成！");
        }
    }

    /**
     * 保存数据
     */
    private void saveData() throws Exception {
        InstanceMonitorServiceImpl monitorService = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        List<MwComponentLayoutInfo> componentLayoutInfos = new ArrayList<>();
        //**** 1:获取所有校验数据 ****
        
        //**** 2:数据校验 ****
        log.info("{}条数据，开始添加模板数据！", list.size());
        if (list.size() > 0) {
            for (ComponentLayoutInfoExcelExportParam importParam : list) {
                MwComponentLayoutInfo layoutInfo = new MwComponentLayoutInfo();
                layoutInfo.setUserId(importParam.getUserId());
                layoutInfo.setComponentLayout(JSONArray.parseArray(importParam.getComponentLayout(),MwTabLayoutInfo.class ));
                layoutInfo.setLabels(JSONArray.parseArray(importParam.getLabels(),MwLayoutLabelInfo.class ));
                layoutInfo.setResolved(importParam.getResolved());
                layoutInfo.setTempName(importParam.getTempName());
                componentLayoutInfos.add(layoutInfo);
            }
        }
        //**** 3:导入数据 ****
        if (CollectionUtils.isNotEmpty(componentLayoutInfos)) {
            monitorService.doBatchAdd(componentLayoutInfos);
        }
        log.info("{}条数据，添加布局数据结束！", componentLayoutInfos.size());
    }

}
